বাংলা

টাইপস্ক্রিপ্ট ব্র্যান্ডেড টাইপস সম্পর্কে জানুন, যা একটি স্ট্রাকচারাল টাইপ সিস্টেমে নমিনাল টাইপিং অর্জনের একটি শক্তিশালী কৌশল। টাইপ নিরাপত্তা এবং কোডের স্বচ্ছতা কীভাবে বাড়ানো যায় তা শিখুন।

টাইপস্ক্রিপ্ট ব্র্যান্ডেড টাইপস: একটি স্ট্রাকচারাল সিস্টেমে নমিনাল টাইপিং

টাইপস্ক্রিপ্টের স্ট্রাকচারাল টাইপ সিস্টেম নমনীয়তা প্রদান করে কিন্তু কখনও কখনও অপ্রত্যাশিত আচরণের কারণ হতে পারে। ব্র্যান্ডেড টাইপস নমিনাল টাইপিং প্রয়োগ করার একটি উপায় প্রদান করে, যা টাইপ নিরাপত্তা এবং কোডের স্বচ্ছতা বৃদ্ধি করে। এই নিবন্ধে ব্র্যান্ডেড টাইপস নিয়ে বিস্তারিত আলোচনা করা হয়েছে, এবং এর বাস্তবায়নের জন্য ব্যবহারিক উদাহরণ ও সেরা অনুশীলন প্রদান করা হয়েছে।

স্ট্রাকচারাল বনাম নমিনাল টাইপিং বোঝা

ব্র্যান্ডেড টাইপস নিয়ে আলোচনা করার আগে, চলুন স্ট্রাকচারাল এবং নমিনাল টাইপিংয়ের মধ্যে পার্থক্য জেনে নেওয়া যাক।

স্ট্রাকচারাল টাইপিং (ডাক টাইপিং)

একটি স্ট্রাকচারাল টাইপ সিস্টেমে, দুটি টাইপকে সামঞ্জস্যপূর্ণ বলে মনে করা হয় যদি তাদের গঠন একই থাকে (অর্থাৎ, একই টাইপের একই প্রোপার্টি থাকে)। টাইপস্ক্রিপ্ট স্ট্রাকচারাল টাইপিং ব্যবহার করে। এই উদাহরণটি বিবেচনা করুন:


interface Point {
  x: number;
  y: number;
}

interface Vector {
  x: number;
  y: number;
}

const point: Point = { x: 10, y: 20 };
const vector: Vector = point; // টাইপস্ক্রিপ্টে বৈধ

console.log(vector.x); // আউটপুট: 10

যদিও Point এবং Vector ভিন্ন টাইপ হিসেবে ঘোষণা করা হয়েছে, টাইপস্ক্রিপ্ট একটি Point অবজেক্টকে একটি Vector ভেরিয়েবলে অ্যাসাইন করার অনুমতি দেয় কারণ তাদের গঠন একই। এটি সুবিধাজনক হতে পারে, কিন্তু এটি ত্রুটির কারণও হতে পারে যদি আপনাকে যৌক্তিকভাবে ভিন্ন টাইপের মধ্যে পার্থক্য করতে হয় যাদের আকৃতি একই। উদাহরণস্বরূপ, অক্ষাংশ/দ্রাঘিমাংশের স্থানাঙ্কের কথা ভাবুন যা ঘটনাক্রমে স্ক্রিন পিক্সেল স্থানাঙ্কের সাথে মিলে যেতে পারে।

নমিনাল টাইপিং

একটি নমিনাল টাইপ সিস্টেমে, টাইপগুলো শুধুমাত্র তখনই সামঞ্জস্যপূর্ণ বলে মনে করা হয় যদি তাদের নাম একই থাকে। এমনকি যদি দুটি টাইপের গঠন একই থাকে, তাদের নাম ভিন্ন হলে তারা ভিন্ন হিসেবে বিবেচিত হয়। জাভা এবং সি#-এর মতো ভাষা নমিনাল টাইপিং ব্যবহার করে।

ব্র্যান্ডেড টাইপসের প্রয়োজনীয়তা

টাইপস্ক্রিপ্টের স্ট্রাকচারাল টাইপিং সমস্যা সৃষ্টি করতে পারে যখন আপনাকে নিশ্চিত করতে হয় যে একটি মান তার গঠন নির্বিশেষে একটি নির্দিষ্ট টাইপের অন্তর্গত। উদাহরণস্বরূপ, মুদ্রা উপস্থাপনার কথা ভাবুন। আপনার কাছে USD এবং EUR এর জন্য ভিন্ন টাইপ থাকতে পারে, কিন্তু উভয়ই সংখ্যা হিসাবে উপস্থাপিত হতে পারে। তাদের মধ্যে পার্থক্য করার কোনো প্রক্রিয়া ছাড়া, আপনি ঘটনাক্রমে ভুল মুদ্রার উপর অপারেশন করতে পারেন।

ব্র্যান্ডেড টাইপস এই সমস্যার সমাধান করে আপনাকে স্বতন্ত্র টাইপ তৈরি করার অনুমতি দিয়ে, যা গঠনগতভাবে একই রকম কিন্তু টাইপ সিস্টেম দ্বারা ভিন্ন হিসেবে বিবেচিত হয়। এটি টাইপ নিরাপত্তা বাড়ায় এবং এমন ত্রুটিগুলো প্রতিরোধ করে যা অন্যথায় এড়িয়ে যেতে পারত।

টাইপস্ক্রিপ্টে ব্র্যান্ডেড টাইপস বাস্তবায়ন

ব্র্যান্ডেড টাইপস ইন্টারসেকশন টাইপস এবং একটি ইউনিক সিম্বল বা স্ট্রিং লিটারেল ব্যবহার করে বাস্তবায়ন করা হয়। মূল ধারণাটি হলো একটি টাইপের সাথে একটি "ব্র্যান্ড" যুক্ত করা যা এটিকে একই কাঠামোর অন্যান্য টাইপ থেকে আলাদা করে।

সিম্বল ব্যবহার করে (সুপারিশকৃত)

ব্র্যান্ডিংয়ের জন্য সিম্বল ব্যবহার করা সাধারণত পছন্দের কারণ সিম্বলগুলো ইউনিক হওয়ার নিশ্চয়তা দেয়।


const USD = Symbol('USD');
type USD = number & { readonly [USD]: unique symbol };

const EUR = Symbol('EUR');
type EUR = number & { readonly [EUR]: unique symbol };

function createUSD(value: number): USD {
  return value as USD;
}

function createEUR(value: number): EUR {
  return value as EUR;
}

function addUSD(a: USD, b: USD): USD {
  return (a + b) as USD;
}

const usd1 = createUSD(10);
const usd2 = createUSD(20);
const eur1 = createEUR(15);

const totalUSD = addUSD(usd1, usd2);
console.log("Total USD:", totalUSD);

// Uncommenting the next line will cause a type error
// const invalidOperation = addUSD(usd1, eur1);

এই উদাহরণে, USD এবং EUR হলো number টাইপের উপর ভিত্তি করে ব্র্যান্ডেড টাইপস। unique symbol নিশ্চিত করে যে এই টাইপগুলো স্বতন্ত্র। createUSD এবং createEUR ফাংশনগুলো এই টাইপের মান তৈরি করতে ব্যবহৃত হয় এবং addUSD ফাংশনটি শুধুমাত্র USD মান গ্রহণ করে। একটি EUR মানকে একটি USD মানের সাথে যোগ করার চেষ্টা করলে একটি টাইপ এরর হবে।

স্ট্রিং লিটারেল ব্যবহার করে

আপনি ব্র্যান্ডিংয়ের জন্য স্ট্রিং লিটারেলও ব্যবহার করতে পারেন, যদিও এই পদ্ধতিটি সিম্বল ব্যবহারের চেয়ে কম শক্তিশালী কারণ স্ট্রিং লিটারেলগুলো ইউনিক হওয়ার নিশ্চয়তা দেয় না।


type USD = number & { readonly __brand: 'USD' };
type EUR = number & { readonly __brand: 'EUR' };

function createUSD(value: number): USD {
  return value as USD;
}

function createEUR(value: number): EUR {
  return value as EUR;
}

function addUSD(a: USD, b: USD): USD {
  return (a + b) as USD;
}

const usd1 = createUSD(10);
const usd2 = createUSD(20);
const eur1 = createEUR(15);

const totalUSD = addUSD(usd1, usd2);
console.log("Total USD:", totalUSD);

// Uncommenting the next line will cause a type error
// const invalidOperation = addUSD(usd1, eur1);

এই উদাহরণটি আগেরটির মতোই ফলাফল অর্জন করে, তবে সিম্বলের পরিবর্তে স্ট্রিং লিটারেল ব্যবহার করে। যদিও এটি সহজ, তবে নিশ্চিত করা গুরুত্বপূর্ণ যে ব্র্যান্ডিংয়ের জন্য ব্যবহৃত স্ট্রিং লিটারেলগুলো আপনার কোডবেসে ইউনিক।

বাস্তব উদাহরণ এবং ব্যবহারের ক্ষেত্র

ব্র্যান্ডেড টাইপস বিভিন্ন পরিস্থিতিতে প্রয়োগ করা যেতে পারে যেখানে স্ট্রাকচারাল সামঞ্জস্যের বাইরেও টাইপ নিরাপত্তা প্রয়োগ করতে হবে।

আইডি (ID)

এমন একটি সিস্টেমের কথা ভাবুন যেখানে বিভিন্ন ধরণের আইডি রয়েছে, যেমন UserID, ProductID, এবং OrderID। এই সমস্ত আইডি সংখ্যা বা স্ট্রিং হিসাবে উপস্থাপিত হতে পারে, কিন্তু আপনি বিভিন্ন ধরনের আইডি ভুলবশত মিশে যাওয়া রোধ করতে চান।


const UserIDBrand = Symbol('UserID');
type UserID = string & { readonly [UserIDBrand]: unique symbol };

const ProductIDBrand = Symbol('ProductID');
type ProductID = string & { readonly [ProductIDBrand]: unique symbol };

function getUser(id: UserID): { name: string } {
  // ... fetch user data
  return { name: "Alice" };
}

function getProduct(id: ProductID): { name: string, price: number } {
  // ... fetch product data
  return { name: "Example Product", price: 25 };
}

function createUserID(id: string): UserID {
  return id as UserID;
}

function createProductID(id: string): ProductID {
  return id as ProductID;
}

const userID = createUserID('user123');
const productID = createProductID('product456');

const user = getUser(userID);
const product = getProduct(productID);

console.log("User:", user);
console.log("Product:", product);

// Uncommenting the next line will cause a type error
// const invalidCall = getUser(productID);

এই উদাহরণটি দেখায় কীভাবে ব্র্যান্ডেড টাইপস একটি ProductID-কে এমন একটি ফাংশনে পাস করা থেকে বিরত রাখতে পারে যা একটি UserID আশা করে, ফলে টাইপ নিরাপত্তা বৃদ্ধি পায়।

ডোমেইন-নির্দিষ্ট মান

ব্র্যান্ডেড টাইপস ডোমেইন-নির্দিষ্ট মানগুলোকে সীমাবদ্ধতার সাথে প্রকাশ করার জন্যও উপযোগী হতে পারে। উদাহরণস্বরূপ, আপনার কাছে শতাংশের জন্য একটি টাইপ থাকতে পারে যা সবসময় ০ থেকে ১০০ এর মধ্যে থাকা উচিত।


const PercentageBrand = Symbol('Percentage');
type Percentage = number & { readonly [PercentageBrand]: unique symbol };

function createPercentage(value: number): Percentage {
  if (value < 0 || value > 100) {
    throw new Error('Percentage must be between 0 and 100');
  }
  return value as Percentage;
}

function applyDiscount(price: number, discount: Percentage): number {
  return price * (1 - discount / 100);
}

try {
  const discount = createPercentage(20);
  const discountedPrice = applyDiscount(100, discount);
  console.log("Discounted Price:", discountedPrice);

  // Uncommenting the next line will cause an error during runtime
  // const invalidPercentage = createPercentage(120);
} catch (error) {
  console.error(error);
}

এই উদাহরণটি দেখায় কীভাবে রানটাইমে একটি ব্র্যান্ডেড টাইপের মানের উপর একটি সীমাবদ্ধতা প্রয়োগ করা যায়। যদিও টাইপ সিস্টেম গ্যারান্টি দিতে পারে না যে একটি Percentage মান সর্বদা ০ থেকে ১০০ এর মধ্যে থাকবে, createPercentage ফাংশনটি রানটাইমে এই সীমাবদ্ধতা প্রয়োগ করতে পারে। ব্র্যান্ডেড টাইপের রানটাইম ভ্যালিডেশন প্রয়োগ করার জন্য আপনি io-ts এর মতো লাইব্রেরিও ব্যবহার করতে পারেন।

তারিখ এবং সময় উপস্থাপনা

বিভিন্ন ফরম্যাট এবং টাইমজোনের কারণে তারিখ এবং সময় নিয়ে কাজ করা জটিল হতে পারে। ব্র্যান্ডেড টাইপস বিভিন্ন তারিখ এবং সময় উপস্থাপনার মধ্যে পার্থক্য করতে সাহায্য করতে পারে।


const UTCDateBrand = Symbol('UTCDate');
type UTCDate = string & { readonly [UTCDateBrand]: unique symbol };

const LocalDateBrand = Symbol('LocalDate');
type LocalDate = string & { readonly [LocalDateBrand]: unique symbol };

function createUTCDate(dateString: string): UTCDate {
  // Validate that the date string is in UTC format (e.g., ISO 8601 with Z)
  if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(dateString)) {
    throw new Error('Invalid UTC date format');
  }
  return dateString as UTCDate;
}

function createLocalDate(dateString: string): LocalDate {
  // Validate that the date string is in local date format (e.g., YYYY-MM-DD)
  if (!/\d{4}-\d{2}-\d{2}/.test(dateString)) {
    throw new Error('Invalid local date format');
  }
  return dateString as LocalDate;
}

function convertUTCDateToLocalDate(utcDate: UTCDate): LocalDate {
  // Perform time zone conversion
  const date = new Date(utcDate);
  const localDateString = date.toLocaleDateString();
  return createLocalDate(localDateString);
}

try {
  const utcDate = createUTCDate('2024-01-20T10:00:00.000Z');
  const localDate = convertUTCDateToLocalDate(utcDate);
  console.log("UTC Date:", utcDate);
  console.log("Local Date:", localDate);
} catch (error) {
  console.error(error);
}

এই উদাহরণটি UTC এবং লোকাল তারিখের মধ্যে পার্থক্য করে, এটি নিশ্চিত করে যে আপনি আপনার অ্যাপ্লিকেশনের বিভিন্ন অংশে সঠিক তারিখ এবং সময় উপস্থাপনা নিয়ে কাজ করছেন। রানটাইম ভ্যালিডেশন নিশ্চিত করে যে শুধুমাত্র সঠিকভাবে ফরম্যাট করা তারিখ স্ট্রিংগুলো এই টাইপগুলোতে অ্যাসাইন করা যেতে পারে।

ব্র্যান্ডেড টাইপস ব্যবহারের সেরা অনুশীলন

টাইপস্ক্রিপ্টে ব্র্যান্ডেড টাইপস কার্যকরভাবে ব্যবহার করার জন্য, নিম্নলিখিত সেরা অনুশীলনগুলো বিবেচনা করুন:

ব্র্যান্ডেড টাইপসের সুবিধা

ব্র্যান্ডেড টাইপসের অসুবিধা

ব্র্যান্ডেড টাইপসের বিকল্প

যদিও ব্র্যান্ডেড টাইপস টাইপস্ক্রিপ্টে নমিনাল টাইপিং অর্জনের একটি শক্তিশালী কৌশল, তবে কিছু বিকল্প পদ্ধতিও রয়েছে যা আপনি বিবেচনা করতে পারেন।

অপেক টাইপস (Opaque Types)

অপেক টাইপস ব্র্যান্ডেড টাইপসের মতোই কিন্তু অন্তর্নিহিত টাইপ লুকানোর জন্য একটি আরও স্পষ্ট উপায় প্রদান করে। টাইপস্ক্রিপ্টে অপেক টাইপসের জন্য বিল্ট-ইন সমর্থন নেই, তবে আপনি মডিউল এবং প্রাইভেট সিম্বল ব্যবহার করে এটি অনুকরণ করতে পারেন।

ক্লাস (Classes)

ক্লাস ব্যবহার করে স্বতন্ত্র টাইপ সংজ্ঞায়িত করার জন্য আরও অবজেক্ট-ওরিয়েন্টেড পদ্ধতি প্রদান করা যেতে পারে। যদিও টাইপস্ক্রিপ্টে ক্লাসগুলো স্ট্রাকচারালি টাইপড, তারা উদ্বেগের একটি পরিষ্কার বিভাজন প্রদান করে এবং মেথডের মাধ্যমে সীমাবদ্ধতা প্রয়োগ করতে ব্যবহার করা যেতে পারে।

io-ts বা zod এর মতো লাইব্রেরি

এই লাইব্রেরিগুলো উন্নত রানটাইম টাইপ ভ্যালিডেশন প্রদান করে এবং কম্পাইল-টাইম এবং রানটাইম উভয় নিরাপত্তা নিশ্চিত করতে ব্র্যান্ডেড টাইপসের সাথে একত্রিত করা যেতে পারে।

উপসংহার

টাইপস্ক্রিপ্ট ব্র্যান্ডেড টাইপস একটি স্ট্রাকচারাল টাইপ সিস্টেমে টাইপ নিরাপত্তা এবং কোডের স্বচ্ছতা বাড়ানোর জন্য একটি মূল্যবান টুল। একটি টাইপের সাথে একটি "ব্র্যান্ড" যুক্ত করে, আপনি নমিনাল টাইপিং প্রয়োগ করতে পারেন এবং গঠনগতভাবে একই রকম কিন্তু যৌক্তিকভাবে ভিন্ন টাইপের আকস্মিক মিশ্রণ প্রতিরোধ করতে পারেন। যদিও ব্র্যান্ডেড টাইপস কিছু জটিলতা এবং ওভারহেড নিয়ে আসে, উন্নত টাইপ নিরাপত্তা এবং কোড রক্ষণাবেক্ষণযোগ্যতার সুবিধাগুলো প্রায়শই অসুবিধাগুলোকে ছাড়িয়ে যায়। এমন পরিস্থিতিতে ব্র্যান্ডেড টাইপস ব্যবহার করার কথা বিবেচনা করুন যেখানে আপনাকে নিশ্চিত করতে হবে যে একটি মান তার গঠন নির্বিশেষে একটি নির্দিষ্ট টাইপের অন্তর্গত।

স্ট্রাকচারাল এবং নমিনাল টাইপিংয়ের পেছনের নীতিগুলো বোঝার মাধ্যমে এবং এই নিবন্ধে বর্ণিত সেরা অনুশীলনগুলো প্রয়োগ করার মাধ্যমে, আপনি আরও শক্তিশালী এবং রক্ষণাবেক্ষণযোগ্য টাইপস্ক্রিপ্ট কোড লিখতে ব্র্যান্ডেড টাইপসকে কার্যকরভাবে ব্যবহার করতে পারেন। মুদ্রা এবং আইডি উপস্থাপন করা থেকে শুরু করে ডোমেইন-নির্দিষ্ট সীমাবদ্ধতা প্রয়োগ করা পর্যন্ত, ব্র্যান্ডেড টাইপস আপনার প্রকল্পগুলোতে টাইপ নিরাপত্তা বাড়ানোর জন্য একটি নমনীয় এবং শক্তিশালী প্রক্রিয়া প্রদান করে।

আপনি যখন টাইপস্ক্রিপ্ট নিয়ে কাজ করবেন, তখন টাইপ ভ্যালিডেশন এবং প্রয়োগের জন্য উপলব্ধ বিভিন্ন কৌশল এবং লাইব্রেরিগুলো অন্বেষণ করুন। টাইপ নিরাপত্তার জন্য একটি ব্যাপক दृष्टिकोण অর্জন করতে io-ts বা zod এর মতো রানটাইম ভ্যালিডেশন লাইব্রেরির সাথে ব্র্যান্ডেড টাইপস ব্যবহার করার কথা বিবেচনা করুন।